﻿using System;
using System.Collections.Generic;
using System.Text;

namespace AMS.DataAccess.Sql
{
    /// <summary>
    /// 表示 SQL 语句中的条件表达式。
    /// 表示一个left op right 的表达式。其中的op运算符
    /// </summary>
    public class SqlCondition : SqlExpression
    {
        /// <summary>
        /// 表示 SQL 语句中的条件表达式。使用等号(=)作为连接操作符
        /// </summary>
        /// <param name="expr">左边操作数</param>
        /// <param name="value">右值</param>
        public SqlCondition(string expr, int value)
            : this(expr, value, SqlOperations.Equals)
        {
        }

        /// <summary>
        /// 表示 SQL 语句中的条件表达式。使用等号(=)作为连接操作符
        /// </summary>
        /// <param name="expr">左边操作数</param>
        /// <param name="value">右值</param>
        public SqlCondition(string expr, string value)
            : this(expr, value, StringOperations.Equals)
        {
        }

        /// <summary>
        /// 表示 SQL 语句中的条件表达式。使用等号(=)作为连接操作符
        /// </summary>
        /// <param name="expr">左边操作数</param>
        /// <param name="value">右值</param>
        public SqlCondition(string expr, bool value)
            : this(expr, value, BooleanOperations.Equals)
        {
        }

        /// <summary>
        /// 构造表达式expr与指示的值value是否相等的条件表达式。
        /// </summary>
        /// <param name="expr">表达式可字段</param>
        /// <param name="value">要比较的时间值</param>
        /// <param name="compareTime">指定是否将时间纳入比较范围。如果将时间纳入，则比较到秒，否则比较到天。</param>
        public SqlCondition(string expr, DateTime value, bool compareTime)
            : this(expr, value, SqlOperations.Equals, compareTime)
        {
        }

        /// <summary>
        /// 构造表达式expr与指示的值value是否相等的条件表达式。
        /// </summary>
        /// <param name="expr">表达式可字段</param>
        /// <param name="value">要比较的时间值。如果operation的值为IsNull或IsNotNull，则这个值将被忽略。</param>
        /// <param name="operation">指定比较方式</param>
        /// <param name="compareTime">指定是否将时间纳入比较范围。如果将时间纳入，则比较到秒，否则比较到天。</param>
        public SqlCondition(string expr, DateTime value, SqlOperations operation, bool compareTime)
        {
            if (operation == SqlOperations.IsNotNull || operation == SqlOperations.IsNull)
            {
                Content.Append(expr);
                Content.Append(SqlEnumUtils.NumberOperationsToString(operation));
            }
            else
            {
                Content.Append("DATEDIFF(");
                Content.Append(compareTime ? "SECOND" : "DAY");
                Content.Append(", ");
                Content.Append(expr);
                Content.Append(", '");
                Content.Append(value.ToString(compareTime ? "yyyy-MM-dd HH:mm:ss" : "yyyy-MM-dd"));
                Content.Append("')");
                Content.Append(SqlEnumUtils.NumberOperationsToString(operation));
                Content.Append("0");
            }
        }

        /// <summary>
        /// 表示 SQL 语句中的条件表达式
        /// </summary>
        /// <param name="expr">左边操作数</param>
        /// <param name="value">右值</param>
        /// <param name="operation">比较操作符</param>
        public SqlCondition(string expr, bool value, BooleanOperations operation)
        {
            Content.Append(expr);
            if (operation == BooleanOperations.Equals)
            {
                Content.Append(" = ");
            }
            else
            {
                Content.Append(" <> ");
            }

            Content.Append(value ? "1" : "0");
        }

        /// <summary>
        /// 表示 SQL 语句中的条件表达式
        /// </summary>
        /// <param name="expr">左边操作数</param>
        /// <param name="value">右值</param>
        /// <param name="operation">比较操作符</param>
        public SqlCondition(string expr, int value, SqlOperations operation)
        {
            BuildNumberCondition(expr, value, operation);
        }
        /// <summary>
        /// 表示 SQL 语句中的条件表达式
        /// </summary>
        /// <param name="expr">左边操作数</param>
        /// <param name="value">右值</param>
        /// <param name="operation">比较操作符</param>
        public SqlCondition(string expr, double value, SqlOperations operation)
        {
            BuildNumberCondition(expr, value, operation);
        }
        /// <summary>
        /// 表示 SQL 语句中的条件表达式
        /// </summary>
        /// <param name="expr">左边操作数</param>
        /// <param name="value">右值</param>
        /// <param name="operation">比较操作符</param>
        public SqlCondition(string expr, decimal value, SqlOperations operation)
        {
            BuildNumberCondition(expr, value, operation);
        }

        private void BuildNumberCondition<T>(string expr, T value, SqlOperations operation)
        {
            Content.Append(expr);
            Content.Append(SqlEnumUtils.NumberOperationsToString(operation));
            if (operation != SqlOperations.IsNotNull && operation != SqlOperations.IsNull)
            {
                Content.Append(value.ToString());
            }
        }

        /// <summary>
        /// 表示 SQL 语句中的条件表达式
        /// </summary>
        /// <param name="expr">左边操作数</param>
        /// <param name="value">右值</param>
        /// <param name="operation">字符串的比较操作符</param>
        public SqlCondition(string expr, string value, StringOperations operation)
        {
            Content.Append(expr);
            if (operation == StringOperations.Like || operation == StringOperations.LeftLike || operation == StringOperations.RightLike)
            {
                Content.Append(SqlEnumUtils.FormatLike(operation, value));
            }
            else
            {
                Content.Append(SqlEnumUtils.StringOperationsToString(operation));
                if (operation != StringOperations.IsNotNull && operation != StringOperations.IsNull)
                {
                    Content.Append(SqlStringUtils.QuotedString(value));
                }
            }
        }
    }

}
